#pragma once

#include "my_rbtree.h"
#include "my_queue.h"
#include "my_thread_base.h"
#include "my_cleanup.h"

#define MY_POOL_PAGE_SIZE                   (1 << 12)
#define MY_PAGE_MAX_ALLOC_SIZE              (1 << 10)
#define MY_POOL_ALLOC_ALIGNED_SIZE          (8)


// manage memory space over MY_PAGE_MAX_ALLOC_SIZE size
typedef struct {
    my_rbtree_node_t                        tree_node;
    void                                    *ptr;
} my_pool_block_node_t;


typedef struct {
    my_queue_t                              queue;
    char                                    *start;
    char                                    *end;
    char                                    *pos;
} my_pool_page_t;


my_pool_page_t *my_pool_page_alloc();
void my_pool_page_free(my_pool_page_t *page);


typedef struct {
    my_queue_t                              pages;
    my_pool_page_t                          *cur_page;
    my_rbtree_t                             block_tree;
    my_rbtree_node_t                        block_sentinel;
    my_cleanup_list_t                       cleanup_list;
} my_pool_t;


my_pool_t *my_pool_create();
void my_pool_destroy(my_pool_t *pool);

void *my_pool_malloc(my_pool_t *pool, size_t size);
void my_pool_free(my_pool_t *pool, void *ptr);

static inline void *
my_pool_calloc(my_pool_t *pool, size_t size)
{
    void *ptr = my_pool_malloc(pool, size);
    bzero(ptr, size);
    return ptr;
}


my_cleanup_item_t *my_pool_add_cleanup(my_pool_t *pool,
    my_cleanup_handler_pt cleanup_handler, void *data);

void my_pool_del_cleanup(my_pool_t *pool,
    my_cleanup_item_t *item);

